Popular Searches
Popular Course Categories
Popular Courses

Firebase Authentication

Firebase with Flutter

Firebase Authentication in Flutter

Firebase Authentication is a Firebase service that provides authentication functionality for Flutter applications. It allows developers to create secure user registration and login systems without building an authentication backend from scratch.

Firebase Authentication supports several authentication methods, including email and password, phone authentication, email-link authentication, and federated identity providers such as Google, Apple, Facebook, and GitHub. The exact providers available depend on the Firebase configuration and platform.


1. What is Firebase Authentication?

Firebase Authentication is a managed authentication service that helps applications identify users and maintain their authentication state.

For example, a Flutter application can allow a user to:

  • Create an account.
  • Log in with an email and password.
  • Log out of the application.
  • Reset a forgotten password.
  • Verify an email address.
  • Sign in using supported identity providers.
  • Monitor whether a user is currently signed in.
  • Access the authenticated user's Firebase UID.

2. Why Use Firebase Authentication with Flutter?

Implementing authentication manually requires creating backend APIs, password handling, sessions, security mechanisms, database integration, and account-management functionality. Firebase Authentication provides managed authentication functionality that can be accessed through the FlutterFire plugin.

Benefits

  • Easy integration with Flutter.
  • Ready-to-use authentication APIs.
  • Supports multiple authentication providers.
  • Provides unique user IDs.
  • Maintains authentication state.
  • Integrates with other Firebase services.
  • Supports authentication state streams.
  • Provides structured authentication errors.
  • Can be combined with Firestore and Storage Security Rules.

3. Firebase Authentication Architecture

Flutter UI
    ↓
Authentication Service
    ↓
FirebaseAuth
    ↓
Firebase Authentication
    ↓
User Account
    ↓
Authentication State
    ↓
Flutter UI

A typical authentication flow looks like this:

Register
   ↓
Firebase Authentication
   ↓
User Account Created
   ↓
User UID
   ↓
Authentication State
   ↓
Home Screen

4. Prerequisites

Before implementing Firebase Authentication, the Flutter application should already be connected to Firebase.

  • Flutter SDK installed.
  • A working Flutter project.
  • A Firebase project.
  • Firebase CLI configured.
  • FlutterFire CLI configured.
  • firebase_options.dart generated using FlutterFire configuration.
  • Firebase initialized in the Flutter application.

If Firebase has not yet been connected to the application, follow the official Firebase Flutter setup process first.


5. Install Firebase Authentication

From the root directory of the Flutter project, install the Firebase Authentication plugin:

flutter pub add firebase_auth

After installing the plugin, rebuild or run the application:

flutter run

The official Firebase Flutter Authentication guide uses the firebase_auth Flutter plugin.


6. Import Firebase Authentication

Import the Firebase Authentication package into the Dart file where authentication functionality is required:

import 'package:firebase_auth/firebase_auth.dart';

7. FirebaseAuth Instance

The FirebaseAuth class provides the main API for authentication operations.

final FirebaseAuth auth = FirebaseAuth.instance;

You can also directly access the singleton instance:

FirebaseAuth.instance

8. Enable an Authentication Provider

Before using an authentication method, the corresponding provider must be enabled in the Firebase Console.

Email and Password

  1. Open the Firebase Console.
  2. Select your Firebase project.
  3. Open Authentication.
  4. Open the Sign-in method section.
  5. Enable Email/Password.
  6. Save the configuration.

The desired sign-in provider must be enabled in the Firebase Console before using it in the application.


9. Email and Password Authentication

Email and password authentication is one of the common authentication methods for Flutter applications.

The basic flow is:

User enters email and password
          ↓
Flutter Login/Register Form
          ↓
FirebaseAuth
          ↓
Firebase Authentication
          ↓
User Account

10. Create a New User Account

Use createUserWithEmailAndPassword() to create an account with an email address and password.

Future registerUser(
  String email,
  String password,
) async {
  try {
    final credential = await FirebaseAuth.instance
        .createUserWithEmailAndPassword(
      email: email,
      password: password,
    );

    print('User created: ${credential.user?.uid}');
  } on FirebaseAuthException catch (e) {
    print('Error: ${e.code}');
    print(e.message);
  }
}

When the account is created successfully, Firebase also signs the user in and makes the authenticated user available through the Firebase Authentication state.


11. Create a Registration Form

A Flutter registration form can collect the user's email and password using TextField or TextFormField.

final emailController = TextEditingController();
final passwordController = TextEditingController();

A simple registration button can call the Firebase Authentication method:

ElevatedButton(
  onPressed: () async {
    await registerUser(
      emailController.text.trim(),
      passwordController.text.trim(),
    );
  },
  child: const Text('Register'),
)

12. Complete Registration Example

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

class RegisterScreen extends StatefulWidget {
  const RegisterScreen({super.key});

  @override
  State createState() => _RegisterScreenState();
}

class _RegisterScreenState extends State {
  final emailController = TextEditingController();
  final passwordController = TextEditingController();

  Future register() async {
    try {
      final credential = await FirebaseAuth.instance
          .createUserWithEmailAndPassword(
        email: emailController.text.trim(),
        password: passwordController.text.trim(),
      );

      if (!mounted) return;

      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
            'Account created: ${credential.user?.email}',
          ),
        ),
      );
    } on FirebaseAuthException catch (e) {
      if (!mounted) return;

      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(e.message ?? 'Registration failed'),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Register'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: emailController,
              keyboardType: TextInputType.emailAddress,
              decoration: const InputDecoration(
                labelText: 'Email',
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: passwordController,
              obscureText: true,
              decoration: const InputDecoration(
                labelText: 'Password',
              ),
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: register,
              child: const Text('Register'),
            ),
          ],
        ),
      ),
    );
  }
}

13. User Login

Use signInWithEmailAndPassword() to authenticate an existing user.

Future loginUser(
  String email,
  String password,
) async {
  try {
    final credential = await FirebaseAuth.instance
        .signInWithEmailAndPassword(
      email: email,
      password: password,
    );

    print('Logged in: ${credential.user?.email}');
  } on FirebaseAuthException catch (e) {
    print('Login error: ${e.code}');
  }
}

14. Complete Login Screen Example

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

class LoginScreen extends StatefulWidget {
  const LoginScreen({super.key});

  @override
  State createState() => _LoginScreenState();
}

class _LoginScreenState extends State {
  final emailController = TextEditingController();
  final passwordController = TextEditingController();

  Future login() async {
    try {
      await FirebaseAuth.instance
          .signInWithEmailAndPassword(
        email: emailController.text.trim(),
        password: passwordController.text.trim(),
      );

      if (!mounted) return;

      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Login successful'),
        ),
      );
    } on FirebaseAuthException catch (e) {
      if (!mounted) return;

      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(e.message ?? 'Login failed'),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Login'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: emailController,
              keyboardType: TextInputType.emailAddress,
              decoration: const InputDecoration(
                labelText: 'Email',
              ),
            ),
            const SizedBox(height: 16),
            TextField(
              controller: passwordController,
              obscureText: true,
              decoration: const InputDecoration(
                labelText: 'Password',
              ),
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: login,
              child: const Text('Login'),
            ),
          ],
        ),
      ),
    );
  }
}

15. Sign Out

Use the signOut() method to log the current user out of the application.

Future logout() async {
  await FirebaseAuth.instance.signOut();
}

Logout Button

ElevatedButton(
  onPressed: () async {
    await FirebaseAuth.instance.signOut();
  },
  child: const Text('Logout'),
)

16. Get the Current User

The currentUser property returns the currently signed-in user, or null when there is no authenticated user.

final User? user = FirebaseAuth.instance.currentUser;

if (user != null) {
  print('UID: ${user.uid}');
  print('Email: ${user.email}');
}

The User object provides information about the authenticated Firebase user.


17. Important User Properties

Property Purpose
uid Unique identifier of the Firebase user.
email User's email address.
displayName User's display name.
photoURL User profile photo URL.
emailVerified Indicates whether the email is verified.
phoneNumber User's phone number when available.
isAnonymous Indicates whether the account is anonymous.

18. Authentication State

Applications often need to know whether the user is logged in or logged out.

Firebase Authentication provides streams for monitoring authentication state changes. The most common method is authStateChanges().

FirebaseAuth.instance
    .authStateChanges()
    .listen((User? user) {
  if (user == null) {
    print('User is signed out');
  } else {
    print('User is signed in');
  }
});

19. Using StreamBuilder with authStateChanges()

In Flutter, StreamBuilder can be used to automatically rebuild the UI whenever the authentication state changes.

StreamBuilder(
  stream: FirebaseAuth.instance.authStateChanges(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }

    if (snapshot.hasData) {
      return const HomeScreen();
    }

    return const LoginScreen();
  },
)

This approach is useful for creating an authentication gate that decides which screen should be displayed based on whether a user is authenticated.


20. Authentication Gate

An authentication gate is a widget that decides whether to display the login screen or the authenticated part of the application.

class AuthGate extends StatelessWidget {
  const AuthGate({super.key});

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          );
        }

        if (snapshot.hasData) {
          return const HomeScreen();
        }

        return const LoginScreen();
      },
    );
  }
}

21. Use AuthGate in main.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  runApp(
    const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: AuthGate(),
    ),
  );
}

This creates a simple authentication flow where Firebase decides whether the application should show the login screen or the home screen.


22. authStateChanges() vs idTokenChanges() vs userChanges()

Firebase Authentication provides three related streams for observing different types of user state changes.

Method Purpose
authStateChanges() Tracks sign-in and sign-out state changes.
idTokenChanges() Tracks authentication state and ID token changes.
userChanges() Tracks authentication state plus supported user-account changes.

For a basic login/logout flow, authStateChanges() is often sufficient.


23. Authentication State Persistence

Firebase Authentication maintains authentication state across application restarts on supported native platforms. On web, authentication persistence can be configured according to the application's requirements.

This means an application can often restore an existing authenticated session instead of requiring the user to log in every time the application starts.


24. Email Verification

After creating an account, an application can send an email verification message.

final user = FirebaseAuth.instance.currentUser;

if (user != null && !user.emailVerified) {
  await user.sendEmailVerification();
}

After the user verifies the email, the application can reload the user and check the updated verification status.

await FirebaseAuth.instance.currentUser?.reload();

final user = FirebaseAuth.instance.currentUser;

if (user?.emailVerified == true) {
  print('Email verified');
}

25. Password Reset

Firebase Authentication provides a password-reset email flow for email/password accounts.

Future resetPassword(String email) async {
  try {
    await FirebaseAuth.instance.sendPasswordResetEmail(
      email: email,
    );

    print('Password reset email sent');
  } on FirebaseAuthException catch (e) {
    print(e.message);
  }
}

Forgot Password Button

TextButton(
  onPressed: () async {
    await resetPassword(
      emailController.text.trim(),
    );
  },
  child: const Text('Forgot Password?'),
)

26. Update User Profile

Authenticated users can update supported profile information such as display name and profile photo URL.

final user = FirebaseAuth.instance.currentUser;

await user?.updateDisplayName('Rahul Sharma');

await user?.updatePhotoURL(
  'https://example.com/profile.jpg',
);

After changing user information, use reload() when you need to refresh the local user object.


27. Change Password

An authenticated user can update their password using updatePassword().

final user = FirebaseAuth.instance.currentUser;

await user?.updatePassword(
  'NewStrongPassword123!',
);

Applications should also handle cases where Firebase requires recent authentication before sensitive account operations.


28. Re-authentication

Some sensitive operations may require the user to have recently authenticated. In such cases, the user can be re-authenticated with their credentials before performing the operation.

final user = FirebaseAuth.instance.currentUser;

final credential = EmailAuthProvider.credential(
  email: user!.email!,
  password: currentPassword,
);

await user.reauthenticateWithCredential(
  credential,
);

After successful re-authentication, the application can retry the sensitive operation.


29. Delete a User Account

An authenticated user can delete their account using delete().

final user = FirebaseAuth.instance.currentUser;

await user?.delete();

For security-sensitive operations, Firebase may require recent authentication before the account can be deleted.


30. Authentication Error Handling

Firebase Authentication errors are exposed in Flutter through FirebaseAuthException. The exception provides an error code and usually a human-readable message.

try {
  await FirebaseAuth.instance.signInWithEmailAndPassword(
    email: email,
    password: password,
  );
} on FirebaseAuthException catch (e) {
  print('Code: ${e.code}');
  print('Message: ${e.message}');
}

31. Common Firebase Authentication Error Codes

Error Code Typical Meaning
invalid-email The email address is invalid.
user-not-found No matching user account was found.
wrong-password The supplied password is incorrect.
weak-password The password does not meet the required strength.
email-already-in-use The email address is already associated with an account.
user-disabled The account has been disabled.
too-many-requests Too many requests have been made in a short period.
network-request-failed A network request could not be completed.

Available error codes depend on the authentication operation and SDK behavior, so applications should handle the codes relevant to their specific flows.


32. User-Friendly Error Messages

Instead of displaying raw technical errors, applications should show understandable messages.

String getAuthErrorMessage(
  FirebaseAuthException error,
) {
  switch (error.code) {
    case 'user-not-found':
      return 'No account was found with this email.';

    case 'wrong-password':
      return 'The password is incorrect.';

    case 'invalid-email':
      return 'Please enter a valid email address.';

    case 'email-already-in-use':
      return 'An account already exists with this email.';

    case 'weak-password':
      return 'Please choose a stronger password.';

    default:
      return 'Authentication failed. Please try again.';
  }
}

33. Form Validation Before Authentication

Client-side validation can prevent unnecessary authentication requests.

if (emailController.text.trim().isEmpty) {
  return;
}

if (passwordController.text.trim().isEmpty) {
  return;
}

A more complete application can use Form, GlobalKey, and TextFormField validators.


34. Registration with Form Validation

final formKey = GlobalKey();

Form(
  key: formKey,
  child: Column(
    children: [
      TextFormField(
        controller: emailController,
        validator: (value) {
          if (value == null || value.trim().isEmpty) {
            return 'Email is required';
          }
          return null;
        },
      ),
      TextFormField(
        controller: passwordController,
        obscureText: true,
        validator: (value) {
          if (value == null || value.length < 6) {
            return 'Password must be at least 6 characters';
          }
          return null;
        },
      ),
      ElevatedButton(
        onPressed: () {
          if (formKey.currentState!.validate()) {
            register();
          }
        },
        child: const Text('Register'),
      ),
    ],
  ),
)

35. Loading State During Authentication

Authentication operations are asynchronous. A loading indicator can prevent duplicate button presses while an operation is running.

bool isLoading = false;

Future login() async {
  setState(() {
    isLoading = true;
  });

  try {
    await FirebaseAuth.instance.signInWithEmailAndPassword(
      email: emailController.text.trim(),
      password: passwordController.text.trim(),
    );
  } on FirebaseAuthException catch (e) {
    print(e.message);
  } finally {
    if (mounted) {
      setState(() {
        isLoading = false;
      });
    }
  }
}

Loading Button

ElevatedButton(
  onPressed: isLoading ? null : login,
  child: isLoading
      ? const CircularProgressIndicator()
      : const Text('Login'),
)

36. Complete Authentication Flow

Application Starts
        ↓
Firebase Initialized
        ↓
AuthGate
        ↓
authStateChanges()
        ↓
   ┌───────────────┐
   │               │
Signed Out      Signed In
   │               │
   ↓               ↓
Login Screen    Home Screen
   │               │
   ↓               ↓
Sign In         Sign Out
   │               │
   └───────┬───────┘
           ↓
    Authentication State
           ↓
       UI Updates

37. Firebase Authentication with Firestore

Authentication and Firestore can be combined to create applications where Firebase Authentication manages the account while Firestore stores additional profile information.

final credential = await FirebaseAuth.instance
    .createUserWithEmailAndPassword(
  email: email,
  password: password,
);

final uid = credential.user!.uid;

await FirebaseFirestore.instance
    .collection('users')
    .doc(uid)
    .set({
  'name': name,
  'email': email,
});

The UID can be used to associate a Firestore document with the authenticated Firebase user.


38. Authentication and Security Rules

Firebase Authentication can work together with Firestore and Storage Security Rules. The authenticated user's identity can be used by security rules to control access to resources.

A simplified Firestore example is:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write:
        if request.auth != null
        && request.auth.uid == userId;
    }
  }
}

This example demonstrates the concept of allowing an authenticated user to access only the document associated with their own UID. Production rules should be designed and tested according to the application's actual authorization requirements.


39. Authentication Providers

Firebase Authentication supports multiple sign-in approaches. The exact configuration depends on the provider and platform.

Authentication Method Description
Email and Password Traditional account registration and login.
Phone Authentication Authentication using a phone number and verification code.
Email Link Passwordless authentication through an email sign-in link.
Google Authentication using a Google account.
Apple Authentication using Apple ID.
Facebook Authentication using Facebook.
GitHub Authentication using GitHub.
Anonymous Allows temporary authenticated sessions without initially requiring user credentials.

Firebase documents these and other supported identity providers and authentication methods.


40. Google Sign-In Concept

Google authentication allows users to authenticate using their Google account. The provider must be configured in the Firebase Console and the Flutter application must implement the provider-specific sign-in flow.

The general flow is:

Flutter Login Button
        ↓
Google Sign-In
        ↓
Google Account
        ↓
Google Credential
        ↓
Firebase Authentication
        ↓
Authenticated Firebase User

41. Phone Authentication Concept

Phone authentication allows users to authenticate using a phone number and verification code.

Enter Phone Number
        ↓
Firebase sends verification code
        ↓
User enters code
        ↓
Firebase verifies code
        ↓
User authenticated

Phone authentication requires additional platform and Firebase configuration, so the provider should be configured according to the official Firebase Flutter documentation.


42. Email Link Authentication

Firebase also supports passwordless email-link authentication. The user receives an email containing a sign-in link and completes authentication through that link.

User enters email
        ↓
Firebase sends sign-in link
        ↓
User opens email
        ↓
User opens sign-in link
        ↓
Firebase verifies link
        ↓
User signed in

Email-link authentication requires appropriate Firebase configuration and application-link handling.


43. Anonymous Authentication

Anonymous authentication allows an application to create a temporary authenticated user without requiring the user to provide credentials initially.

Future signInAnonymously() async {
  try {
    final credential =
        await FirebaseAuth.instance.signInAnonymously();

    print('Anonymous UID: ${credential.user?.uid}');
  } on FirebaseAuthException catch (e) {
    print(e.message);
  }
}

This can be useful when an application wants to provide authenticated access before the user creates a permanent account.


44. Link Authentication Providers

Firebase Authentication can support linking multiple authentication credentials to an existing user account where the provider and platform support the flow.

This allows a user to use more than one supported sign-in method for the same Firebase account.

final user = FirebaseAuth.instance.currentUser;

if (user != null) {
  await user.linkWithCredential(credential);
}

45. Authentication Service Class

For larger applications, authentication logic can be placed inside a dedicated service class.

import 'package:firebase_auth/firebase_auth.dart';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  User? get currentUser => _auth.currentUser;

  Stream get authStateChanges =>
      _auth.authStateChanges();

  Future register(
    String email,
    String password,
  ) {
    return _auth.createUserWithEmailAndPassword(
      email: email,
      password: password,
    );
  }

  Future login(
    String email,
    String password,
  ) {
    return _auth.signInWithEmailAndPassword(
      email: email,
      password: password,
    );
  }

  Future logout() {
    return _auth.signOut();
  }
}

Advantages

  • Centralizes authentication logic.
  • Keeps widgets cleaner.
  • Makes methods reusable.
  • Improves maintainability.
  • Makes testing easier.

46. Recommended Authentication Project Structure

lib/
├── main.dart
├── firebase_options.dart
├── models/
│   └── user_model.dart
├── services/
│   └── auth_service.dart
├── screens/
│   ├── login_screen.dart
│   ├── register_screen.dart
│   ├── forgot_password_screen.dart
│   └── home_screen.dart
├── widgets/
│   ├── auth_button.dart
│   └── auth_text_field.dart
└── providers/
    └── auth_provider.dart

47. Authentication Best Practices

  1. Use Firebase Authentication rather than implementing password storage yourself.
  2. Enable only the authentication providers required by the application.
  3. Validate form fields before making authentication requests.
  4. Handle FirebaseAuthException properly.
  5. Show user-friendly error messages.
  6. Disable login/register buttons while an operation is in progress.
  7. Use authStateChanges() for authentication-gate scenarios.
  8. Use the authenticated user's UID when associating Firebase data with a user.
  9. Protect Firestore and Storage resources with Security Rules.
  10. Use email verification when appropriate for the application.
  11. Use secure password requirements appropriate to the application's needs.
  12. Do not store passwords manually in Firestore.
  13. Keep authentication logic separate from large UI widgets.
  14. Test authentication flows thoroughly.

48. Common Firebase Authentication Mistakes

  • Forgetting to enable Email/Password in the Firebase Console.
  • Forgetting to add the firebase_auth package.
  • Using Firebase Authentication before initializing Firebase.
  • Not handling FirebaseAuthException.
  • Not validating email and password fields.
  • Allowing users to repeatedly press a login button while a request is running.
  • Displaying raw technical error messages to users.
  • Not handling the signed-out state.
  • Putting authentication listeners inside a widget's build() method.
  • Not protecting Firestore data with appropriate Security Rules.
  • Assuming authentication automatically protects every Firebase resource.

Note: Authentication listeners should be structured so that a new listener is not unnecessarily created on every widget rebuild.


49. Login and Registration Flow

                 Flutter App
                      |
             ┌────────┴────────┐
             ↓                 ↓
         Register            Login
             ↓                 ↓
   createUserWith...   signInWith...
             ↓                 ↓
             └────────┬────────┘
                      ↓
               Firebase Auth
                      ↓
                User Account
                      ↓
              Authentication
                  State
                      ↓
                 Home Screen

50. Complete Authentication Example

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  Stream get authStateChanges =>
      _auth.authStateChanges();

  Future register(
    String email,
    String password,
  ) async {
    await _auth.createUserWithEmailAndPassword(
      email: email,
      password: password,
    );
  }

  Future login(
    String email,
    String password,
  ) async {
    await _auth.signInWithEmailAndPassword(
      email: email,
      password: password,
    );
  }

  Future logout() async {
    await _auth.signOut();
  }
}

class AuthGate extends StatelessWidget {
  const AuthGate({super.key});

  @override
  Widget build(BuildContext context) {
    final authService = AuthService();

    return StreamBuilder(
      stream: authService.authStateChanges,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          );
        }

        if (snapshot.hasData) {
          return const HomeScreen();
        }

        return const LoginScreen();
      },
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            await FirebaseAuth.instance.signOut();
          },
          child: const Text('Logout'),
        ),
      ),
    );
  }
}

class LoginScreen extends StatelessWidget {
  const LoginScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('Login Screen'),
      ),
    );
  }
}

51. Firebase Authentication Security

Authentication is only one part of application security. After identifying the user, Firebase Security Rules should be used to determine what authenticated users are allowed to read or write.

Authentication
      ↓
User Identity
      ↓
UID
      ↓
Security Rules
      ↓
Authorized Resource Access

For example, a user's UID can be used to restrict access to their own Firestore document.


52. Authentication with User Profiles

Firebase Authentication stores account identity information, while Firestore can store application-specific profile information.

Firebase Authentication
└── UID
    ├── Email
    └── Authentication State
Cloud Firestore
└── users
    └── UID
        ├── Name
        ├── Course
        ├── Age
        └── Profile Image

This separation allows authentication and application data to serve different purposes.


53. Practice Project: Firebase Login System

Create a Flutter application with a complete Firebase Authentication system.

Requirements

  1. Create a Firebase project.
  2. Connect the Flutter application with Firebase.
  3. Add the firebase_auth package.
  4. Enable Email/Password authentication.
  5. Create a registration screen.
  6. Create a login screen.
  7. Implement email validation.
  8. Implement password validation.
  9. Implement user registration.
  10. Implement user login.
  11. Implement logout.
  12. Create an authentication gate.
  13. Display the current user's email on the home screen.
  14. Add forgot-password functionality.
  15. Add email verification.
  16. Handle authentication errors.
  17. Add loading states.

54. Suggested Application Structure

Firebase Authentication App
│
├── Splash / Auth Gate
│
├── Login
│   ├── Email
│   ├── Password
│   ├── Login Button
│   └── Forgot Password
│
├── Register
│   ├── Email
│   ├── Password
│   ├── Confirm Password
│   └── Register Button
│
└── Home
    ├── User Email
    ├── User UID
    └── Logout

55. Interview Questions

Q1. What is Firebase Authentication?

Firebase Authentication is a managed Firebase service that provides user authentication functionality for applications.

Q2. How do you add Firebase Authentication to Flutter?

flutter pub add firebase_auth

Q3. How do you create a user with email and password?

await FirebaseAuth.instance
    .createUserWithEmailAndPassword(
  email: email,
  password: password,
);

Q4. How do you sign in a user?

await FirebaseAuth.instance
    .signInWithEmailAndPassword(
  email: email,
  password: password,
);

Q5. How do you sign out?

await FirebaseAuth.instance.signOut();

Q6. How do you get the current user?

FirebaseAuth.instance.currentUser

Q7. How can you monitor authentication state?

FirebaseAuth.instance.authStateChanges()

Q8. What is authStateChanges()?

It provides a stream that emits authentication state and subsequent changes such as sign-in and sign-out.

Q9. What is FirebaseAuthException?

It is the Flutter Firebase Authentication exception type used to expose authentication errors and their codes.

Q10. Why are Security Rules important?

Authentication identifies users, while Security Rules help control what those users can access or modify in Firebase resources.


56. Quick Revision Table

Topic Important Code
Install Auth flutter pub add firebase_auth
Import Auth import 'package:firebase_auth/firebase_auth.dart';
Auth Instance FirebaseAuth.instance
Register createUserWithEmailAndPassword()
Login signInWithEmailAndPassword()
Logout signOut()
Current User currentUser
Auth State authStateChanges()
Reset Password sendPasswordResetEmail()
Email Verification sendEmailVerification()
Update Name updateDisplayName()
Update Photo updatePhotoURL()
Update Password updatePassword()
Delete Account delete()
Error Handling FirebaseAuthException

57. Useful Resources


58. JustAcademy Flutter Resources


59. Summary

Firebase Authentication provides a complete authentication system that can be integrated into Flutter applications using the firebase_auth plugin. Developers can implement registration, login, logout, password reset, email verification, authentication-state monitoring, profile management, and multiple supported sign-in providers.

The basic workflow is to connect the Flutter application with Firebase, add firebase_auth, enable the required provider in the Firebase Console, implement the authentication methods, handle FirebaseAuthException, and use authStateChanges() or another appropriate authentication-state stream to update the Flutter UI.

For production applications, authentication should be combined with appropriate Firebase Security Rules, validation, error handling, and secure application architecture.

whatsapp